function [d, off, sz] = minarray(d, minthresh, maxthresh, fringe)
% minarray  - minimize array size
%
% FORMAT:       [d, off, sz] = minarray(d, minthresh, maxthresh, fringe)
%
% Input fields:
%
%       d           2d or 3d numeric data array
%       minthresh   minimum value (default: 0, > comparison)
%       maxthresh   maximum value (default: Inf, <= comparison)
%       fringe      added after border find (default: 0)
%
% Output fields:
%
%       d           minimized array
%       off         offset (1-based)
%       sz          new array size

% Version:  v0.7a
% Build:    7082418
% Date:     Aug-24 2007, 6:16 PM CEST
% Author:   Jochen Weber, Brain Innovation, B.V., Maastricht, NL
% URL/Info: http://wiki.brainvoyager.com/BVQXtools

% argument check
if nargin < 1 || ...
   ~isnumeric(d)
    error( ...
        'BVQXtools:BadArgument', ...
        'Bad or missing argument.' ...
    );
end
sz = size(d);
if isempty(d)
    off = [1, 1, 1];
    return;
end
if nargin < 2 || ...
   ~isnumeric(minthresh) || ...
    isempty(minthresh)
    minthresh = 0;
else
    minthresh = minthresh(1);
end
try
    minthresh = eval([class(d) '(minthresh)']);
catch
    % do nothing
end
if nargin < 3 || ...
   ~isnumeric(maxthresh) || ...
    isempty(maxthresh)
    maxthresh = Inf;
else
    maxthresh = maxthresh(1);
end
try
    maxthresh = eval([class(d) '(maxthresh)']);
catch
    % do nothing
end
if nargin < 4 || ...
   ~isnumeric(fringe) || ...
    numel(fringe) ~= 1 || ...
    isnan(fringe) || ...
    fringe < 0 || ...
    fringe > 512 || ...
    fringe ~= fix(fringe)
    fringe = 0;
end

% first find X border
nxc = [sz(2) * sz(3), 1];
for x1 = 1:sz(1)
    if any(reshape(d(x1, :, :), nxc) > minthresh) && ...
        any(reshape(d(x1, :, :), nxc) <= maxthresh)
        break;
    end
end
for xe = sz(1):-1:x1
    if any(reshape(d(xe, :, :), nxc) > minthresh) && ...
        any(reshape(d(xe, :, :), nxc) <= maxthresh)
        break;
    end
end
sxc = x1:xe;

% find Y border
nyc = [numel(sxc) * sz(3), 1];
for y1 = 1:sz(2)
    if any(reshape(d(sxc, y1, :), nyc) > minthresh) && ...
        any(reshape(d(sxc, y1, :), nyc) <= maxthresh)
        break;
    end
end
for ye = sz(2):-1:y1
    if any(reshape(d(sxc, ye, :), nyc) > minthresh) && ...
        any(reshape(d(sxc, ye, :), nyc) <= maxthresh)
        break;
    end
end
syc = y1:ye;

% find Z border
nzc = [numel(sxc) * numel(syc), 1];
for z1 = 1:sz(3)
    if any(reshape(d(sxc, syc, z1), nzc) > minthresh) && ...
        any(reshape(d(sxc, syc, z1), nzc) <= maxthresh)
        break;
    end
end
for ze = sz(3):-1:z1
    if any(reshape(d(sxc, syc, ze), nzc) > minthresh) && ...
        any(reshape(d(sxc, syc, ze), nzc) <= maxthresh)
        break;
    end
end

% fringe
x1 = max(1, x1 - fringe);
xe = min(sz(1), xe + fringe);
y1 = max(1, y1 - fringe);
ye = min(sz(2), ye + fringe);
z1 = max(1, z1 - fringe);
ze = min(sz(3), ze + fringe);

% reframe data
d = d(x1:xe, y1:ye, z1:ze);
off = [x1, y1, z1];
sz = size(d);
